COMP3141 Software System Design and Implementation

COMP3141: Software System Design and Implementation

Term 2, 2023

Code and Notes (Week 1 Wednesday)

Table of Contents

1 Live code

This is all the code I wrote during the lecture. No guarantee that it makes any sense out of context.

-- modules are mainly used for namespaces
-- to acces that from outside
-- I would go FirstLecture.x
module FirstLecture where

{- Alternative titles:

  Introduction to Mathematically Structured Programming


  I can't believe it's not a Haskell course!

 -}
-- inline comment

-- Ints, Doubles

{-
  int square(int x) {
    return(x*x);
  }

 -}

-- the first line is a *function signature*
-- it specifies the name and type of the function
-- function types look like this:
--      a -> b
-- a is the *domain* of the function
--  aka the argument type
-- b is the *codomain* of the function
--  aka the return type
square :: Int -> Int

-- next comes the function *definition*
-- the LHS names the parameter x
-- the RHS is an expression describing
-- the return value of the function
square x = x*x

{- This is (kind of) a mathematical function:
   it maps an input to an output,
   and does absolutely nothing else
 -}

{- These are *not* like variables in
   C, Java, Python...

   They're more like constants.

   I will sometimes call them variables
   anyway.
   (More proper term might be "bindings")
 -}
--x :: Int
--x = 7

myLogBase :: Double -> Double -> Double
myLogBase = logBase
{- Q: Why doesn't this function specify
      its arguments?
   A: I could have but it doesn't matter.

      If I have a function f that takes an
      argument x, and returns g x

      then f = g

      technical term: eta-equivalence

   When we make a declaration
     name <args> = <body>

   The LHS and RHS need to have the same type
-}
myOtherLogBase :: Double -> Double -> Double
myOtherLogBase x y = logBase x y

{- myLogBase is a function, which
   -- given a Double, returns:
   -- a function of type Double -> Double

 -}

{- Functions are first-class citizens:
     functions are values that can be
     used in all the same ways as
        Doubles, Ints, Bools, ...
   You can have lists of functions
   You can give functions as arguments
     to other functions
   You can return functions from functions
 -}

{-  myLogBase 10
      *is* the 10:th logarithm function
    myLogBase 2
      is the binary logarithm function
 -}

-- Technically, haskell functions are
-- from exactly one argument
-- to exactly one argument

{- This technique is called Currying

  Because this is  done *all the time*
  There's some syntactical conventions:

  Function application is left associative

    f x y = (f x) y

  Conversely, the arrow in type signatures
   (called function arrow) is
  right associative

   a -> b -> c  this means a -> (b -> c)
 -}

{- The arithmetic operators
     + - * / div
   are also curried functions


   1 + 2 is sugar for

   (+) 1 2


   1 `div` 2 is sugar for

   div 1 2

   Symbolic identifiers are infix,
   but can be treated as prefix by
   surrounding them with parens

   Alphanumeric identifiers are prefix,
   but can be treated as infix by
   surrounding them with backticks
 -}

{- This  declaration defines the constant
   x  in terms of itself

  "Let x = x + 1"

  In order to calculate the value of x:
  Step 1: get the value x
  Step 2: add 1 to the value of x
 -}
--x = x + 1

-- declarative vs imperative programming

-- Function application syntax



-- Chars, Strings

-- Lists

-- String in Haskell is a
-- synonym of [Char]

-- List in Haskell (singly-linked lists)
-- are of two primitive kinds
-- the empty list: []
-- cons blocks     (:)
--  If x is an element
--  and xs is a list
--  then x:xs  is also a list

-- [a,b,c] is sugar for
-- a:b:c:[]

-- Every element in a list must have
-- the same type

-- Multi-argument functions
-- Pairs

-- if x and y are values of possibly types
--  x::a   and y::b
-- then (x,y) : (a,b)

divmod :: Int -> Int -> (Int,Int)
divmod x y = (x `div` y, x `mod` y)

2023-08-13 Sun 12:51

Announcements RSS